package cn.peach.user.service.impl;

import cn.peach.basic.exception.MyException;
import cn.peach.basic.util.StrUtils;
import cn.peach.user.constant.UserConstant;
import cn.peach.user.domain.User;
import cn.peach.user.mapper.UserMapper;
import cn.peach.user.service.IVerifycodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 */
@Service
public class VerifycodeServiceImpl implements IVerifycodeService {

    @Autowired // 注入用户 需要获取用户的手机号 以及用户的需求 验证码发送给用户
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void smsCode(Map<String, String> param) {
        System.out.println(param);
        String phone = param.get("phone");
        String type = param.get("type");
        // 1. 手机号不能为空
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)) {
            throw new MyException("手机号不能为空");
        }
        String redisKey = null;
        if (type.equals("register")) {
            // 2. 看是否为空来判断手机号是否已存在 要先通过userMapper自定义方法获取手机号 给出异常提示信息t_user
            User user = userMapper.getPhone(phone);
            if (user != null) {
                throw new MyException("该手机号已被注册");
            }
            redisKey = UserConstant.REGISTER_PREFIX + phone;
            sendCode(redisKey);
        } else if (type.equals("binder")) {
            redisKey = UserConstant.BINDER_PREFIX + phone;
            sendCode(redisKey);
        }
    }

    /**
     * 发送验证码校验
     * @param redisKey
     */
    private void sendCode(String redisKey) {
        // 3. 验证码三分钟过期， 从redis中取，如果能取到，就说明没有过期
        // key就是业务标识+手机号    register_prefix+phone
        Object code = redisTemplate.opsForValue().get(redisKey);
        String timeCode = null;
        if (code != null){
            // 3.1. 如果不为空就获取时间戳判断当前验证码是否超过一分钟，没有超过一分钟，直接提示：验证码已发送
            String time = code.toString().split(":")[0];
            // 用当前时间戳减发送验证码时的时间戳 看是否小于一分钟
            if (System.currentTimeMillis() - Long.valueOf(time) <= 1*60*1000){
                throw new MyException("验证码已发送，请勿重复点击");
            }else{
                // 3.2. 超过一分钟，重新刷新之前验证码的过期时间
                timeCode = code.toString().split(":")[1];
            }
        }else {
            // 4. 如果取不到， 就说明验证码已经过期了需要通过StrUtils重新生成验证码
            timeCode = StrUtils.getComplexRandomString(4);
        }
        // 重新生成验证码
        redisTemplate.opsForValue().set(redisKey, System.currentTimeMillis() + ":" + timeCode,
                3L, TimeUnit.MINUTES);
        System.out.println(timeCode);
    }
}

